package com.project.restaurant.order.listener;

import com.project.restaurant.mapper.OrderMapper;
import com.project.restaurant.order.dto.QRPayInfo;
import com.project.restaurant.order.enums.OrderState;
import com.project.restaurant.order.listener.event.QRPaySuccessEvent;
import com.project.restaurant.order.listener.event.QRPayTimeEvent;
import com.project.restaurant.redis.key.RedisKey;
import com.project.restaurant.redis.service.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

@Component
public class QRPayInfoListener {

    private static ExecutorService pool = Executors.newFixedThreadPool(10);
    /**
     * 存放所有要监视的支付订单。
     * 如果支付订单已经支付，会有QRPaySuccessEvent事件发布，则会触发listenQRPaySuccessEvent方法，从中移除监听的线程
     * 如果支付的订单过时，则延迟线程会自动将订单设为取消状态，即无法被支付
     */
    private static Map<String,Future<?>> monitorPayMap = new HashMap<>();
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    RedisClient redisClient;


    @EventListener
    public void listenQRPaySuccessEvent(QRPaySuccessEvent event){
        //获取事件里的数据
        String orderId = (String) event.getSource();
        //获取该支付成功的订单的延时线程
        Future<?> monitor = monitorPayMap.get(orderId);
        //取消该线程的执行
        if(monitor!=null){
            monitor.cancel(false);
            monitorPayMap.remove(orderId);
        }
        redisClient.delKey(RedisKey.ORDER_PAY_URL+orderId);
    }

    @EventListener
    public void listenQRPayTimeEvent(QRPayTimeEvent event){
        QRPayInfo source = (QRPayInfo) event.getSource();
        Future<?> monitor = pool.submit(() -> {
            try {
                Thread.sleep(1800000);
//                Thread.sleep(30000);
                orderMapper.updateOrderState(source.getOrderId(),OrderState.CANCEL_PAY.getOrderState());
                //移除监听的线程
                monitorPayMap.remove(source.getOrderId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        monitorPayMap.put(source.getOrderId(),monitor);
    }


}
